#include "include/gudb.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    // Open database
    gudb* db = gudb_open("./test_client_db", GU_OPEN_CREATE, "admin", "admin");
    if (!db) {
        printf("Failed to open database\n");
        return 1;
    }
    
    // Begin transaction
    gudb_txn* txn = gudb_begin(db, GU_TXN_RC, "gudb");
    if (!txn) {
        printf("Failed to begin transaction\n");
        gudb_close(db);
        return 1;
    }
    
    result_t* result = NULL;
    
    printf("=== Client Behavior Test ===\n");
    
    // Clean slate
    printf("Cleaning up...\n");
    gudb_exec(txn, "DROP DATABASE IF EXISTS testdb1", NULL, &result);
    if (result) gudb_free_result(result);
    gudb_exec(txn, "DROP DATABASE IF EXISTS testdb2", NULL, &result);
    if (result) gudb_free_result(result);
    
    // Create test databases
    printf("Creating test databases...\n");
    gudb_exec(txn, "CREATE DATABASE testdb1", NULL, &result);
    if (result) gudb_free_result(result);
    gudb_exec(txn, "CREATE DATABASE testdb2", NULL, &result);
    if (result) gudb_free_result(result);
    
    // Test sequence that might cause issues
    printf("\n--- Test Sequence ---\n");
    
    // 1. Start in default database
    printf("1. Current database tables:\n");
    if (gudb_exec(txn, "SHOW TABLES", NULL, &result) == GU_OK) {
        for (uint32_t i = 0; i < result->row_count; i++) {
            printf("   %s\n", result->rows[i][0]);
        }
        if (result->row_count == 0) printf("   (empty)\n");
        gudb_free_result(result);
    }
    
    // 2. Create table in default database  
    printf("2. Creating table in default database...\n");
    gudb_exec(txn, "CREATE TABLE default_table (id INT)", NULL, &result);
    if (result) gudb_free_result(result);
    
    // 3. Switch to testdb1
    printf("3. Switching to testdb1...\n");
    gudb_exec(txn, "USE testdb1", NULL, &result);
    if (result) gudb_free_result(result);
    
    // 4. Show tables in testdb1 (should be empty)
    printf("4. Tables in testdb1:\n");
    if (gudb_exec(txn, "SHOW TABLES", NULL, &result) == GU_OK) {
        for (uint32_t i = 0; i < result->row_count; i++) {
            printf("   %s (ERROR: Should not see this!)\n", result->rows[i][0]);
        }
        if (result->row_count == 0) printf("   (empty - correct!)\n");
        gudb_free_result(result);
    }
    
    // 5. Create table in testdb1
    printf("5. Creating table in testdb1...\n");
    gudb_exec(txn, "CREATE TABLE testdb1_table (id INT)", NULL, &result);
    if (result) gudb_free_result(result);
    
    // 6. Show tables in testdb1 (should show testdb1_table)
    printf("6. Tables in testdb1 after creation:\n");
    if (gudb_exec(txn, "SHOW TABLES", NULL, &result) == GU_OK) {
        for (uint32_t i = 0; i < result->row_count; i++) {
            if (strcmp(result->rows[i][0], "testdb1_table") == 0) {
                printf("   %s (correct!)\n", result->rows[i][0]);
            } else {
                printf("   %s (ERROR: This shouldn't be here!)\n", result->rows[i][0]);
            }
        }
        gudb_free_result(result);
    }
    
    // 7. Switch to testdb2
    printf("7. Switching to testdb2...\n");
    gudb_exec(txn, "USE testdb2", NULL, &result);
    if (result) gudb_free_result(result);
    
    // 8. Show tables in testdb2 (should be empty)
    printf("8. Tables in testdb2:\n");
    if (gudb_exec(txn, "SHOW TABLES", NULL, &result) == GU_OK) {
        for (uint32_t i = 0; i < result->row_count; i++) {
            printf("   %s (ERROR: Should not see any tables!)\n", result->rows[i][0]);
        }
        if (result->row_count == 0) printf("   (empty - correct!)\n");
        gudb_free_result(result);
    }
    
    // 9. Try to drop table from testdb1 while in testdb2
    printf("9. Trying to drop testdb1_table while in testdb2...\n");
    if (gudb_exec(txn, "DROP TABLE testdb1_table", NULL, &result) == GU_OK) {
        printf("   ERROR: Successfully dropped table from different database!\n");
        if (result) gudb_free_result(result);
    } else {
        printf("   Good: Failed to drop table (table not found in current database)\n");
    }
    
    // 10. Switch back to testdb1 and verify table still exists
    printf("10. Switching back to testdb1 to verify table...\n");
    gudb_exec(txn, "USE testdb1", NULL, &result);
    if (result) gudb_free_result(result);
    
    if (gudb_exec(txn, "SHOW TABLES", NULL, &result) == GU_OK) {
        bool found_table = false;
        for (uint32_t i = 0; i < result->row_count; i++) {
            if (strcmp(result->rows[i][0], "testdb1_table") == 0) {
                printf("   testdb1_table still exists (good!)\n");
                found_table = true;
            } else {
                printf("   %s (unexpected table)\n", result->rows[i][0]);
            }
        }
        if (!found_table && result->row_count == 0) {
            printf("   ERROR: testdb1_table disappeared!\n");
        }
        gudb_free_result(result);
    }
    
    // Cleanup
    gudb_commit(txn);
    gudb_close(db);
    
    printf("\n=== Test completed ===\n");
    return 0;
}